package com.xcity.pomelo.response;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import com.xcity.db.entity.Employee;
import com.xcity.db.entity.Player;
import com.xcity.game.assist.AssistBuild;
import com.xcity.game.buildv2.BuildUtils;
import com.xcity.game.buildv2.BuildV2;
import com.xcity.game.buildv2.BuildV2.State;
import com.xcity.game.buildv2.BuildV2Part;
import com.xcity.game.buildv2.template.BuildTemplateV2;
import com.xcity.game.buildv2.template.BuildTemplateV2.PartTemplate;
import com.xcity.game.item.ItemTemplate;
import com.xcity.pomelo.response.EmployeeInfoResponse.EmployeeSimpleInfo;

import naga.x.game.time.TimeUpdater;
import naga.x.net.impl.pomelo.PomeloMessage;
import naga.x.net.impl.pomelo.protocol.Message;

@PomeloMessage(type = Message.Type.RESPONSE)
public class BuildV2Response extends Response {
	
	public int id;
	public String name;
	public String image;
	public State state;
	public int partsLvl; // 所有部位等级总和
	public Part[] parts; // 建筑部位（state=BUILDING时才有该属性）
	public Invader invader; // 侵占者信息
	public List<com.xcity.pomelo.response.EmployeeInfoResponse.EmployeeSimpleInfo> employees = Collections.emptyList();
	//建筑加金钱信息
	public int nextTakeSecond;//貌似已经没用了//0~1800 -1为不可领 距离下次领钱还有多少秒
	public int takeMoneyElapseSec;//距离上次开始产钱多少秒  如果是-1则已经停止产钱
	public int addMoneyFactor;//float
	//建筑加经验信息
//	public int takeExpElapseSecond;//距离上次领取多少秒 用于判断是否可领
//	public int lastPutExpBookSecond;//距离上次放经验书多少秒 用于判断技能书什么时候耗完 -1没放书
//	public int[] putEmployeeSeconds;//距离上次放员工多少秒 4个槽记4次 用于判断可领多少经验 -1没员工
	public ExpBookTempInfo expBookInfo;//经验书相关简化模版信息 没有为空
	public ExpExtendInfo expExtendInfo;//建筑产经验扩展信息
	public int stageId; // 解锁该建筑需通关的关卡id
	public Assistant assistant;// 协助防御者
//	public long assTime = 0;// 开始协助防御时间 只有有assistant的时候才显示时间
	public int assLeftSec = 0;//协助防御时间剩余(秒) 负数为已经到时间
	
	// 建筑部位
	public static class Part {
		public int index; // 部位索引
		public int level;
//		public Material item; // 所需材料
//		public int gold; // 所需现金
		public Require[] requires; // 各等级所需资源（10个等级）
		public byte state; // 状态（0-被损坏；1-正常；2-已满级）
		public static final byte STATE_BROKEN = 0, STATE_NORMAL = 1, STATE_FULL_LEVEL = 2;
		public Part() {}
		public Part(Player player, BuildV2Part ref) {
			this.index = ref.getIndex();
			this.level = ref.getLevel();
//			PartTemplate partTemplate = ref.template;
//			int count, needCount;
//			int nextLvl;
//			if (level >= BuildV2Part.MAX_LEVEL) {
//				count = needCount = partTemplate.getItemCount(nextLvl = BuildV2Part.MAX_LEVEL);
//			} else {
//				count = player.getBag().countOf(partTemplate.itemId);
//				needCount = partTemplate.getItemCount(nextLvl = level + 1);
//				if (count > needCount) {
//					count = needCount;
//				}
//			}
//			this.item = new Material(partTemplate.getItem(), count, needCount);
//			this.gold = partTemplate.getGold(nextLvl);
			PartTemplate partTemplate = ref.template;
			this.requires = new Require[BuildV2Part.MAX_LEVEL];
			for (int i = 0; i < this.requires.length; i++) {
				int level = i + 1;
				Material item = new Material(partTemplate.getItem(), partTemplate.getItemCount(level));
				this.requires[i] = new Require(item, partTemplate.getGold(level));
			}
			this.state = level >= BuildV2Part.MAX_LEVEL ? Part.STATE_FULL_LEVEL : ref.getState();
		}
	}
	
	public static class Require {
		public Material item; // 需求物品
		public int gold; // 需求现金
		public Require(Material item, int gold) {
			this.item = item;
			this.gold = gold;
		}
	}
	
	// 材料（物品）
	public static class Material {
		private ItemTemplate template;
		public int count; // 需求数量
		public Material(ItemTemplate template, int count) {
			this.template = template;
			this.count = count;
		}
		public int getId() {
			return template.getId();
		}
	}
	
	public static class Invader {
		public long id;
		public String name;
		public String icon;
		public byte sex;
		public int level;
		public Invader() {}
		public Invader(Player player) {
			this.id = player.getId();
			this.name = player.getName();
			this.icon = player.getIcon();
			this.sex = player.getSex();
			this.level = player.getLevel();
		}
	}
	
	public static class Assistant{
		public long assistId;
		public String name;
		public List<com.xcity.pomelo.response.EmployeeInfoResponse.EmployeeSimpleInfo> employees = Collections.emptyList();
		
		public Assistant(Player player, AssistBuild assbuild){
			this.assistId = player.getId();
			this.name = player.getName();
			long[] eids = assbuild.getEmployees();
			this.employees = new ArrayList<>(eids.length);
			for (long eid : eids) {
				Employee e;
				if (eid == 0L || (e = player.getEmployees().get(eid)) == null) {
					this.employees.add(EmployeeSimpleInfo.EMPTY);
				} else {
					this.employees.add(new EmployeeSimpleInfo(e));
				}
			}
		}
	}
	
	//经验书(物品)
	public static class ExpBookTempInfo{
		private ItemTemplate template;
		public ExpBookTempInfo(ItemTemplate temp){
			template = temp;
		}
		
		public int getItemId(){
			return this.template.getId();
		}
		
		public String getName(){
			return this.template.getName();
		}
		
		public String getIcon(){
			return this.template.getIcon();
		}
		
		public int getTotalSecond(){
			return this.template.getParameter(1, 0) * 60;
		}
		
		public int getTotalExp(){
			return this.template.getParameter(0);
		}
	}
	//建筑产经验扩展信息
	public static class ExpExtendInfo{
		private BuildV2 build;
		public ExpExtendInfo(BuildV2 build){
			this.build = build;
		}
		//领取经验剩余秒数 0到时 -1不可领
		public int getTakeExpLeftSecond(){
			return build.calcTakeExpLeftSecond();
		}
		//经验书剩余秒数 0 剩余0秒 -1没放书
		public int getExpBookLeftSecond(){
			return build.calcExpBookLeftSecond();
		}
		//距离上次放员工多少秒 4个槽记4次 用于判断可领多少经验 -1没员工
		public int[] getPutEmployeeElapseSeconds(){
			int[] putEmployeeSeconds = new int[BuildV2.MAX_SLOT];
			for(int i = 0; i < BuildV2.MAX_SLOT; i++){
				//四个员工 每个已经放了多少秒
				putEmployeeSeconds[i] = build.employeePutSecondBySlotIndex(i);
			}
			return putEmployeeSeconds;
		}
	}
	
	public BuildV2Response(int serial, Player player, BuildV2 building) {
		super(serial);
		this.id = building.getId();
		BuildTemplateV2 template = building.getTemplate();
		this.name = template.getName();
		this.image = template.getImage();
		
		Player invader = building.currentInvader();
		Player owner = building.getVm().getOwner(); 
		if (invader != null) {
			this.invader = new Invader(invader);
			owner = invader;
		}
		long[] eids = building.currentEmployees();
		if (eids != null && eids.length > 0) {
			this.employees = new ArrayList<>(eids.length);
			for (long eid : eids) {
				Employee e;
				if (eid == 0L || (e = owner.getEmployees().get(eid)) == null) {
					this.employees.add(EmployeeSimpleInfo.EMPTY);
				} else {
					this.employees.add(new EmployeeSimpleInfo(e));
				}
			}
		}
		//建筑员工加金钱
		this.nextTakeSecond = -1;//2017.06.16 暂时弃用这个值building.nextTakeMoneyLeftSecond();
		this.takeMoneyElapseSec = building.calcTakeMoneyElapseSecond();
		this.addMoneyFactor = template.getProduceMoneyFactor();//(float)template.getProduceMoneyFactor() / 100;
//		//建筑员工加经验
//		this.takeExpElapseSecond = building.calcTakeExpElapseSecond();
//		this.lastPutExpBookSecond = building.calcLastPutExpBookSecond();
//		for(int i = 0; i < BuildV2.MAX_SLOT; i++){
//			//四个员工 每个已经放了多少秒
//			this.putEmployeeSeconds[i] = building.employeePutSecondBySlotIndex(i);
//		}
		ItemTemplate itemTemplate = building.tryGetExpBookTemplate();
		if(itemTemplate != null){
			this.expBookInfo = new ExpBookTempInfo(itemTemplate);
		}
		this.expExtendInfo = new ExpExtendInfo(building);
		this.stageId = template.getUnlockStage() != null ? template.getUnlockStage().getId() : 0;
		
		Player assistant = building.currentAssistant();
		if(assistant != null){
			AssistBuild assbuild = assistant.getAssists().findByOwnerId(player.getId());
			if(assbuild != null){
				this.assistant = new Assistant(assistant, assbuild);
				long endTime = building.getAssistTime() + BuildV2.BUILD_RETURN_MILLISECOND;
				long now = TimeUpdater.getInstance().now();
				this.assLeftSec = (int) ((endTime - now)/1000L);
				this.takeMoneyElapseSec = (int)((now - assbuild.getLastStartMakeMoneyTime())/1000L);
				if(assbuild.getLastStartMakeMoneyTime() > endTime){
					this.takeMoneyElapseSec = -1;
				}
			}
		}
		
		// 合服后，invader/assistant可能为空导致state改变
		this.state = building.getState();
		if (this.state == State.BUILDING) {
			BuildV2Part[] partsRef = building.getParts();
			int len = partsRef.length;
			this.parts = new Part[len];
			for (int i = 0; i < len; i++) {
				BuildV2Part ref = partsRef[i];
				Part p = new Part(player, ref);
				this.parts[i] = p;
				this.partsLvl += ref.getLevel();
			}
		}
	}
	
	public BuildV2Response(int serial, Player player, BuildTemplateV2 template) {
		super(serial);
		this.id = template.getId();
		this.name = template.getName();
		this.image = template.getImage();
		this.state = BuildUtils.isUnlock(player, template) ? State.UNLOCKED : State.LOCKED;
//		int len = BuildV2.PART_COUNT;
//		this.parts = new Part[len];
//		for (int i = 0; i < len; i++) {
//			PartTemplate partTemplate = template.getPart(i);
//			Part p = new Part();
//			p.index = i;
//			p.level = 0;
////			p.item = new Material(partTemplate.getItem(), 0, partTemplate.getItemCount(1));
////			p.gold = partTemplate.getGold(1);
//			p.state = Part.STATE_NORMAL;
//			this.parts[i] = p;
//		}
		this.addMoneyFactor = template.getProduceMoneyFactor();//(float)template.getProduceMoneyFactor() / 100;
		this.nextTakeSecond = -1;
		this.stageId = template.getUnlockStage() != null ? template.getUnlockStage().getId() : 0;
	}

}
